home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / util / moni / Scout-src.lha / source / objects / scout_system.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-09-17  |  19.7 KB  |  592 lines

  1. /**
  2.  * Scout - The Amiga System Monitor
  3.  *
  4.  *------------------------------------------------------------------
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * You must not use this source code to gain profit of any kind!
  21.  *
  22.  *------------------------------------------------------------------
  23.  *
  24.  * @author Andreas Gelhausen
  25.  * @author Richard Körber <rkoerber@gmx.de>
  26.  */
  27.  
  28. #include "system_headers.h"
  29.  
  30. static __asm __saveds LONG syslist_con2func(register __a2 Object *obj, register __a1 struct NList_ConstructMessage *msg, register __a0 struct Hook *hook)
  31. {
  32.     return AllocListEntry(msg->pool, msg->entry, sizeof(struct SystemEntry));
  33. }
  34.  
  35. MakeHook(syslist_con2hook, syslist_con2func);
  36.  
  37. static __asm __saveds LONG syslist_des2func(register __a2 Object *obj, register __a1 struct NList_DestructMessage *msg, register __a0 struct Hook *hook)
  38. {
  39.     FreeListEntry(msg->pool, &msg->entry);
  40.  
  41.     return 0;
  42. }
  43.  
  44. MakeHook(syslist_des2hook, syslist_des2func);
  45.  
  46. static __asm __saveds LONG syslist_dsp2func(register __a2 Object *obj, register __a1 struct NList_DisplayMessage *msg, register __a0 struct Hook *hook)
  47. {
  48.     struct SystemEntry *se = (struct SystemEntry *)msg->entry;
  49.  
  50.     if (se) {
  51.         msg->strings[0] = se->se_Description;
  52.         msg->strings[1] = se->se_Line;
  53.     }
  54.  
  55.     return 0;
  56. }
  57.  
  58. MakeHook(syslist_dsp2hook, syslist_dsp2func);
  59.  
  60.  
  61.  
  62.  
  63.  
  64. static STRPTR MyIdHardware( ULONG num )
  65. {
  66.     if (IdentifyBase) {
  67.         return IdHardwareTags(num, IDTAG_Localize, FALSE, TAG_DONE);
  68.     } else {
  69.         return msgNoIdentifyLibrary;
  70.     }
  71. }
  72.  
  73. static int MyIdCheck( ULONG num )
  74. {
  75.     if (IdentifyBase) {
  76.         return (int)IdHardwareTags(num, IDTAG_NULL4NA, TRUE, TAG_DONE);
  77.     } else {
  78.         return 0;
  79.     }
  80. }
  81.  
  82. static void DateToInt( struct DateStamp *ds,
  83.                        ULONG *u )
  84. {
  85.     *u = SMult32(ds->ds_Days, 86400) +
  86.          SMult32(ds->ds_Minute, 60) +
  87.          SDivMod32(ds->ds_Tick, TICKS_PER_SECOND);
  88. }
  89.  
  90. static void IntToDate( ULONG r,
  91.                        struct DateStamp *ds )
  92. {
  93.     ds->ds_Days = UDivMod32(r, 86400);
  94.  
  95.     r = getreg(REG_D1);
  96.     ds->ds_Minute = UDivMod32(r, 60);
  97.  
  98.     r = getreg(REG_D1);
  99.     ds->ds_Tick = UMult32(r, TICKS_PER_SECOND);
  100. }
  101.  
  102. static void addentry( void (* callback)( struct SystemEntry *se, void *userData ),
  103.                       void *userData,
  104.                       UBYTE *desc,
  105.                       UBYTE *linefmt, ... )
  106. {
  107.     struct SystemEntry *se;
  108.  
  109.     if (se = tbAllocVecPooled(globalPool, sizeof(struct SystemEntry))) {
  110.         va_list args;
  111.  
  112.         if (desc) stccpy(se->se_Description, desc, sizeof(se->se_Description));
  113.  
  114.         if (linefmt) {
  115.             va_start(args, linefmt);
  116.             _vsnprintf(se->se_Line, sizeof(se->se_Line), linefmt, args);
  117.             va_end(args);
  118.         }
  119.  
  120.         callback(se, userData);
  121.  
  122.         tbFreeVecPooled(globalPool, se);
  123.     }
  124. }
  125.  
  126. static void ReceiveList( void (* callback)( struct SystemEntry *se, void *userData ),
  127.                          void *userData )
  128. {
  129.     struct SystemEntry *se;
  130.  
  131.     if (se = tbAllocVecPooled(globalPool, sizeof(struct SystemEntry))) {
  132.         if (SendDaemon("GetSysList")) {
  133.             while (ReceiveDecodedEntry((UBYTE *)se, sizeof(struct SystemEntry))) {
  134.                 callback(se, userData);
  135.             }
  136.         }
  137.  
  138.         tbFreeVecPooled(globalPool, se);
  139.     }
  140. }
  141.  
  142. static void IterateList( void (* callback)( struct SystemEntry *se, void *userData ),
  143.                          void *userData )
  144. {
  145.     UBYTE tmp[PATH_LENGTH];
  146.     ULONG cacr, pcr;
  147.     UWORD attn;
  148.     BPTR lock;
  149.     ULONG lastalert, lastalerttask;
  150.     BOOL fblit;
  151.  
  152.     if (IdentifyBase) IdHardwareUpdate(); // Liste auf dem aktuellsten Stand
  153.  
  154.     cacr = GetCACR(); /* 68020..68060 */
  155.     pcr  = GetPCR();  /* 68060 */
  156.     attn = SysBase->AttnFlags;
  157.  
  158.     addentry(callback, userData, NULL, MUIX_C MUIX_PH "-- HARDWARE --" MUIX_PT);
  159.  
  160.     addentry(callback, userData, NULL, NULL);
  161.  
  162.     addentry(callback, userData, "System", "%s", MyIdHardware(IDHW_SYSTEM));
  163.  
  164.     addentry(callback, userData, NULL, NULL);
  165.  
  166.     if (MyIdCheck(IDHW_CPUREV)) {
  167.         addentry(callback, userData, "Processor", "CPU: %s / %s (ID $%04lx, Rev %s)", MyIdHardware(IDHW_CPU), MyIdHardware(IDHW_CPUCLOCK), pcr >> 16, MyIdHardware(IDHW_CPUREV));
  168.     } else {
  169.         addentry(callback, userData, "Processor", "CPU: %s / %s", MyIdHardware(IDHW_CPU), MyIdHardware(IDHW_CPUCLOCK));
  170.     }
  171.  
  172.     if (MyIdCheck(IDHW_FPU)) {
  173.         addentry(callback, userData, NULL, "FPU: %s / %s", MyIdHardware(IDHW_FPU), MyIdHardware(IDHW_FPUCLOCK));
  174.     }
  175.  
  176.     if (MyIdCheck(IDHW_MMU)) {
  177.         addentry(callback, userData, NULL, "MMU: %s", MyIdHardware(IDHW_MMU));
  178.     }
  179.  
  180.     if (MyIdCheck(IDHW_POWERPC)) {
  181.         addentry(callback, userData, NULL, "PPC: %s / %s", MyIdHardware(IDHW_POWERPC), MyIdHardware(IDHW_PPCCLOCK));
  182.     }
  183.  
  184.     addentry(callback, userData, NULL, NULL);
  185.  
  186.     addentry(callback, userData, "Chipset", "%s, RamSey %s, Gary %s", MyIdHardware(IDHW_CHIPSET), MyIdHardware(IDHW_RAMSEY), MyIdHardware(IDHW_GARY));
  187.  
  188.     addentry(callback, userData, NULL, "ChunkyPlanar %s, BattClock %s", MyIdHardware(IDHW_CHUNKYPLANAR), MyIdHardware(IDHW_BATTCLOCK));
  189.  
  190.     Forbid();
  191.     fblit = (FindPort("FBlit") != NULL);
  192.     Permit();
  193.  
  194.     addentry(callback, userData, NULL, "FBlit %s", (fblit) ? "found" : "not running");
  195.  
  196.     addentry(callback, userData, "Mother RAM", "%s Bit, %s Access, %s CAS, %sx Bandwidth", MyIdHardware(IDHW_RAMWIDTH), MyIdHardware(IDHW_RAMACCESS), MyIdHardware(IDHW_RAMCAS), MyIdHardware(IDHW_RAMBANDWIDTH));
  197.  
  198.     addentry(callback, userData, "Frequencies", "VBlank %s, Power %s, E %s", MyIdHardware(IDHW_VBLANKFREQ), MyIdHardware(IDHW_POWERFREQ), MyIdHardware(IDHW_ECLOCK));
  199.  
  200.     addentry(callback, userData, NULL, NULL);
  201.     addentry(callback, userData, NULL, NULL);
  202.  
  203.     addentry(callback, userData, NULL, MUIX_C MUIX_PH "-- REGISTERS --" MUIX_PT);
  204.  
  205.     addentry(callback, userData, NULL, NULL);
  206.  
  207.     addentry(callback, userData, NULL, "SSP:  $%08lx", SysBase->SysStkLower);
  208.  
  209.     if (attn & AFF_68010) {
  210.         ULONG cache = CacheControl(0, 0);
  211.  
  212.         addentry(callback, userData, NULL, "VBR:  $%08lx",GetVBR());
  213.  
  214.         if (attn & AFF_68020) {
  215.             addentry(callback, userData, NULL, "CACR: $%08lx",cacr);
  216.         }
  217.  
  218.         if (attn & AFF_68060) {
  219.             addentry(callback, userData, NULL, "PCR:  $%08lx",pcr);
  220.         }
  221.  
  222.         addentry(callback, userData, NULL, NULL);
  223.  
  224.         if (attn & AFF_68020) {
  225.             if (cache & CACRF_EnableI) {
  226.                 stccpy(tmp, "Enabled ", sizeof(tmp));
  227.                 if ((attn & AFF_68030) && !(attn & AFF_68040) && (cache & CACRF_IBE)) _strcatn(tmp, "Burst ", PATH_LENGTH);
  228.                 if (cache & CACRF_FreezeI) _strcatn(tmp, "Frozen ", PATH_LENGTH);
  229.                 if ((attn & AFF_68060) && (cacr & (1 << 13))) _strcatn(tmp, "Half ", PATH_LENGTH);
  230.             } else {
  231.                 stccpy(tmp, "Disabled", sizeof(tmp));
  232.             }
  233.             addentry(callback, userData, "Inst Cache", tmp);
  234.         }
  235.  
  236.         if (attn & AFF_68030) {
  237.             if (cache & CACRF_EnableD) {
  238.                 stccpy(tmp, "Enabled ", sizeof(tmp));
  239.                 if ((attn & AFF_68030) && !(attn & AFF_68040) && (cache & CACRF_DBE)) _strcatn(tmp, "Burst ", PATH_LENGTH);
  240.                 if (cache & CACRF_FreezeD) _strcatn(tmp, "Frozen ", PATH_LENGTH);
  241.                 if ((attn & AFF_68060) && (cacr & (1 << 27))) _strcatn(tmp, "Half ", PATH_LENGTH);
  242.                 if ((attn & AFF_68030) && !(attn & AFF_68040) && (cache & CACRF_WriteAllocate)) _strcatn(tmp, "Allocate ", PATH_LENGTH);
  243.             } else {
  244.                 stccpy(tmp, "Disabled", sizeof(tmp));
  245.             }
  246.             addentry(callback, userData, "Data Cache", tmp);
  247.         }
  248.  
  249.         if ((attn & AFF_68040) && !(attn & AFF_68060) && (cache & CACRF_CopyBack)) {
  250.             addentry(callback, userData, NULL, "CopyBack");
  251.         }
  252.  
  253.         if (cache & CACRF_EnableE){
  254.             addentry(callback, userData, NULL, "External Cache");
  255.         }
  256.  
  257.         if (attn & AFF_68060) {
  258.             if (pcr & (1 << 0)) {
  259.                 addentry(callback, userData, NULL, "Superscalar");
  260.             }
  261.  
  262.             if (cacr & (1 << 23)) {
  263.                 addentry(callback, userData, NULL, "Branch Cache");
  264.             }
  265.  
  266.             if (cacr & (1 << 29)) {
  267.                 addentry(callback, userData, NULL, "Store Buffer");
  268.             }
  269.  
  270.             if (cacr & (1 << 28)) {
  271.                 addentry(callback, userData, NULL, "CPUSH invalidation disabled");
  272.             }
  273.  
  274.             if (pcr & (1 << 1)) {
  275.                 addentry(callback, userData, NULL, "FPU disabled");
  276.             }
  277.         }
  278.     }
  279.  
  280.     addentry(callback, userData, NULL, NULL);
  281.     addentry(callback, userData, NULL, NULL);
  282.  
  283.     if (lock = Lock("RAM:", SHARED_LOCK)) {
  284.         struct InfoData *id;
  285.  
  286.         if (id = tbAllocVecPooled(globalPool, sizeof(struct InfoData))) {
  287.             if (Info(lock, id)) {
  288.                 struct DeviceList *ramDev;
  289.                 ULONG currentTime, bootTime, upTime;
  290.                 struct DateStamp ds;
  291.                 struct DateTime dt;
  292.                 UBYTE dateStr[LEN_DATSTRING], timeStr[LEN_DATSTRING];
  293.  
  294.                 ramDev = BADDR(id->id_VolumeNode);
  295.                 DateToInt(&ramDev->dl_VolumeDate, &bootTime);
  296.  
  297.                 DateStamp(&ds);
  298.                 DateToInt(&ds, ¤tTime);
  299.  
  300.                 upTime = currentTime - bootTime;
  301.  
  302.                 addentry(callback, userData, NULL, MUIX_C MUIX_PH "-- UPTIME --");
  303.  
  304.                 addentry(callback, userData, NULL, NULL);
  305.  
  306.                 IntToDate(currentTime, &dt.dat_Stamp);
  307.                 dt.dat_Format = FORMAT_DOS;
  308.                 dt.dat_Flags = 0;
  309.                 dt.dat_StrDay = NULL;
  310.                 dt.dat_StrDate = dateStr;
  311.                 dt.dat_StrTime = timeStr;
  312.                 DateToStr(&dt);
  313.  
  314.                 addentry(callback, userData, "Current time", "%s %s", dateStr, timeStr);
  315.  
  316.                 IntToDate(bootTime, &dt.dat_Stamp);
  317.                 dt.dat_Format = FORMAT_DOS;
  318.                 dt.dat_Flags = 0;
  319.                 dt.dat_StrDay = NULL;
  320.                 dt.dat_StrDate = dateStr;
  321.                 dt.dat_StrTime = timeStr;
  322.                 DateToStr(&dt);
  323.  
  324.                 addentry(callback, userData, "Boot time", "%s %s", dateStr, timeStr);
  325.  
  326.                 IntToDate(upTime, &dt.dat_Stamp);
  327.                 dt.dat_Format = FORMAT_DOS;
  328.                 dt.dat_Flags = 0;
  329.                 dt.dat_StrDay = NULL;
  330.                 dt.dat_StrDate = NULL;
  331.                 dt.dat_StrTime = timeStr;
  332.                 DateToStr(&dt);
  333.  
  334.                 addentry(callback, userData, "Uptime", "%4ld days, %s hours", dt.dat_Stamp.ds_Days, timeStr);
  335.             }
  336.  
  337.             tbFreeVecPooled(globalPool, id);
  338.         }
  339.  
  340.         UnLock(lock);
  341.     }
  342.  
  343.     addentry(callback, userData, NULL, NULL);
  344.     addentry(callback, userData, NULL, NULL);
  345.  
  346.     addentry(callback, userData, NULL, MUIX_C MUIX_PH "-- VERSIONS --" MUIX_PT);
  347.  
  348.     addentry(callback, userData, NULL, NULL);
  349.  
  350.     addentry(callback, userData, "AmigaOS", "%s (= %s), SetPatch %s, ROM %s", MyIdHardware(IDHW_OSNR), MyIdHardware(IDHW_OSVER), MyIdHardware(IDHW_SETPATCHVER), MyIdHardware(IDHW_ROMSIZE));
  351.  
  352.     addentry(callback, userData, "Exec", "%s", MyIdHardware(IDHW_EXECVER));
  353.  
  354.     addentry(callback, userData, "Workbench", "%s", MyIdHardware(IDHW_WBVER));
  355.  
  356.     addentry(callback, userData, "Graphics", "%s", MyIdHardware(IDHW_GFXSYS));
  357.  
  358.     addentry(callback, userData, "Audio", "%s", MyIdHardware(IDHW_AUDIOSYS));
  359.  
  360.     addentry(callback, userData, "TCP/IP", "%s", MyIdHardware(IDHW_TCPIP));
  361.  
  362.     addentry(callback, userData, "PowerPC-OS", "%s", MyIdHardware(IDHW_PPCOS));
  363.  
  364.     addentry(callback, userData, NULL, NULL);
  365.     addentry(callback, userData, NULL, NULL);
  366.  
  367.     addentry(callback, userData, NULL, MUIX_C MUIX_PH "-- MEMORY --" MUIX_PT);
  368.  
  369.     addentry(callback, userData, NULL, NULL);
  370.  
  371.     addentry(callback, userData, NULL, " Chip       Fast      TOTAL");
  372.  
  373.     addentry(callback, userData, "Plain", "%9s  %9s  %9s", MyIdHardware(IDHW_PLNCHIPRAM), MyIdHardware(IDHW_PLNFASTRAM), MyIdHardware(IDHW_PLNRAM));
  374.  
  375.     addentry(callback, userData, "Virtual", "%9s  %9s  %9s", MyIdHardware(IDHW_VMMCHIPRAM), MyIdHardware(IDHW_VMMFASTRAM), MyIdHardware(IDHW_VMMRAM));
  376.  
  377.     addentry(callback, userData, "TOTAL", "%9s  %9s  %9s", MyIdHardware(IDHW_CHIPRAM), MyIdHardware(IDHW_FASTRAM), MyIdHardware(IDHW_RAM));
  378.  
  379.     addentry(callback, userData, NULL, NULL);
  380.  
  381.     addentry(callback, userData, NULL, "SlowRAM: %s", MyIdHardware(IDHW_SLOWRAM));
  382.  
  383.     // no more calls to identify.library to detect the last alert, as this will either
  384.     // return wrong results or cause an Enforcer hit
  385.     // lastalert = IdHardwareNum(IDHW_LASTALERT, NULL);
  386.     if (MMUBase) {
  387.         // if we have THOR's mmu.library installed it is very simple to get the last Guru and the task
  388.         // that caused it without causing an Enforcer hit ourself.
  389.         struct MMUContext *ctx;
  390.         ULONG zerobase;
  391.  
  392.         ctx = DefaultContext();
  393.         LockMMUContext(ctx);
  394.  
  395.         zerobase = GetMMUContextData(ctx, MCXTAG_ZEROBASE);
  396.         ReadZeroPage(zerobase, &lastalert, &lastalerttask);
  397.  
  398.         UnlockMMUContext(ctx);
  399.     } else {
  400.         // if you used some non-mmu.library tool to remap the ZeroPage this is the only way to get the correct values
  401.         // Sorry, but this will definitely cause an Enforce hit!! No way 'round...
  402.         lastalert = *((ULONG *)0x100);
  403.         lastalerttask = *((ULONG *)0x104);
  404.     }
  405.     if (lastalert != 0xFFFFFFFF) {
  406.         struct Task *alerttask;
  407.  
  408.         addentry(callback, userData, NULL, NULL);
  409.         addentry(callback, userData, NULL, NULL);
  410.  
  411.         addentry(callback, userData, NULL, MUIX_C MUIX_PH "-- LAST ALERT --" MUIX_PT);
  412.  
  413.         addentry(callback, userData, NULL, NULL);
  414.  
  415.         addentry(callback, userData, "Alert Code", "%08lx", lastalert);
  416.  
  417.         if (alerttask = TaskExists((struct Task *)lastalerttask)) {
  418.             GetTaskName(alerttask, tmp, sizeof(tmp));
  419.             addentry(callback, userData, "Alert Task", "$%08lx (%s)", lastalerttask, tmp);
  420.         } else {
  421.             addentry(callback, userData, "Alert Task", "$%08lx", lastalerttask);
  422.         }
  423.  
  424.         if (IdentifyBase) {
  425.             IdAlertTags(lastalert, IDTAG_DeadStr, tmp, TAG_DONE);
  426.             addentry(callback, userData, "Deadend", tmp);
  427.  
  428.             IdAlertTags(lastalert, IDTAG_SubsysStr, tmp, TAG_DONE);
  429.             addentry(callback, userData, "Sub System", tmp);
  430.  
  431.             IdAlertTags(lastalert, IDTAG_GeneralStr, tmp, TAG_DONE);
  432.             addentry(callback, userData, "General", tmp);
  433.  
  434.             IdAlertTags(lastalert, IDTAG_SpecStr, tmp, TAG_DONE);
  435.             addentry(callback, userData, "Specific", tmp);
  436.         }
  437.     }
  438. }
  439.  
  440. static void UpdateCallback( struct SystemEntry *se,
  441.                             void *userData )
  442. {
  443.     InsertBottomEntry(userData, se);
  444. }
  445.  
  446. static void PrintCallback( struct SystemEntry *se,
  447.                            void *userData )
  448. {
  449.     UBYTE *desc, *line;
  450.  
  451.     desc = se->se_Description;
  452.     while (*desc=='\33') desc += 2;
  453.  
  454.     line = se->se_Line;
  455.     while (*line=='\33') line += 2;
  456.  
  457.     PrintFOneLine((BPTR)userData, " %15s  %s\n", desc, line);
  458. }
  459.  
  460. static void SendCallback( struct SystemEntry *se,
  461.                           void *userData )
  462. {
  463.     SendEncodedEntry((UBYTE *)se, sizeof(struct SystemEntry));
  464. }
  465.  
  466. static ULONG __saveds mNew( struct IClass *cl,
  467.                             Object *obj,
  468.                             struct opSet *msg )
  469. {
  470.     APTR sysList, updateButton, printButton, exitButton;
  471.  
  472.     if (obj = (Object *)DoSuperNew(cl, obj,
  473.         MUIA_HelpNode, SystemText,
  474.         MUIA_Window_ID, MakeID('S','Y','S','T'),
  475.         WindowContents, VGroup,
  476.  
  477.             Child, sysList = NListviewObject,
  478.                MUIA_CycleChain, TRUE,
  479.                MUIA_NListview_NList, NListObject,
  480.                 MUIA_Font, MUIV_Font_Fixed,
  481.                    MUIA_NList_Input, FALSE,
  482.                    MUIA_NList_Format, "BAR P=" MUIX_R ",BAR",
  483.                    MUIA_NList_ConstructHook2, &syslist_con2hook, 
  484.                    MUIA_NList_DestructHook2, &syslist_des2hook, 
  485.                    MUIA_NList_DisplayHook2, &syslist_dsp2hook,
  486.                End,
  487.             End,
  488.  
  489.             Child, MyVSpace(4),
  490.  
  491.             Child, HGroup, MUIA_Group_SameSize, TRUE,
  492.                 Child, updateButton = MakeButton(txtUpdate),
  493.                 Child, printButton  = MakeButton(txtPrint),
  494.                 Child, exitButton   = MakeButton(txtExit),
  495.             End,
  496.         End,
  497.         TAG_MORE, msg->ops_AttrList))
  498.     {
  499.         struct SystemWinData *swd = INST_DATA(cl, obj);
  500.         APTR parent;
  501.  
  502.         swd->swd_SystemList = sysList;
  503.  
  504.         parent = (APTR)GetTagData(MUIA_Window_ParentWindow, (ULONG)NULL, msg->ops_AttrList);
  505.  
  506.         set(obj, MUIA_Window_Title, MyGetWindowTitle("SYSTEM", swd->swd_Title, sizeof(swd->swd_Title)));
  507.         set(obj, MUIA_Window_ActiveObject, sysList);
  508.  
  509.         DoMethod(parent,       MUIM_Window_AddChildWindow, obj);
  510.         DoMethod(obj,          MUIM_Notify, MUIA_Window_CloseRequest, TRUE,  MUIV_Notify_Application, 5, MUIM_Application_PushMethod, parent, 2, MUIM_Window_RemChildWindow, obj);
  511.         DoMethod(updateButton, MUIM_Notify, MUIA_Pressed,             FALSE, obj,                     1, MUIM_SystemWin_Update);
  512.         DoMethod(printButton,  MUIM_Notify, MUIA_Pressed,             FALSE, obj,                     1, MUIM_SystemWin_Print);
  513.         DoMethod(exitButton,   MUIM_Notify, MUIA_Pressed,             FALSE, obj,                     3, MUIM_Set, MUIA_Window_CloseRequest, TRUE);
  514.     }
  515.  
  516.     return (ULONG)obj;
  517. }
  518.  
  519. static ULONG __saveds mDispose( struct IClass *cl,
  520.                                 Object *obj,
  521.                                 struct opSet *msg )
  522. {
  523.     struct SystemWinData *swd = INST_DATA(cl, obj);
  524.  
  525.     set(obj, MUIA_Window_Open, FALSE);
  526.     DoMethod(swd->swd_SystemList, MUIM_NList_Clear);
  527.  
  528.     return (DoSuperMethodA(cl, obj, msg));
  529. }
  530.  
  531. static ULONG __saveds mUpdate( struct IClass *cl,
  532.                                Object *obj,
  533.                                Msg msg )
  534. {
  535.     struct SystemWinData *swd = INST_DATA(cl, obj);
  536.  
  537.     ApplicationSleep(TRUE);
  538.     set(swd->swd_SystemList, MUIA_List_Quiet, TRUE);
  539.     DoMethod(swd->swd_SystemList, MUIM_List_Clear);
  540.  
  541.     if (clientstate) {
  542.         ReceiveList(UpdateCallback, swd->swd_SystemList);
  543.     } else {
  544.         IterateList(UpdateCallback, swd->swd_SystemList);
  545.     }
  546.  
  547.     set(swd->swd_SystemList, MUIA_List_Quiet, FALSE);
  548.     ApplicationSleep(FALSE);
  549.  
  550.     return 0;
  551. }
  552.  
  553. static ULONG __saveds mPrint( struct IClass *cl,
  554.                               Object *obj,
  555.                               Msg msg )
  556. {
  557.     PrintSystem(NULL);
  558.  
  559.     return 0;
  560. }
  561.  
  562. ULONG __asm __saveds SystemWinDispatcher( register __a0 struct IClass *cl,
  563.                                           register __a2 Object *obj,
  564.                                           register __a1 Msg msg )
  565. {
  566.     switch (msg->MethodID) {
  567.         case OM_NEW:                return (mNew(cl, obj, (APTR)msg));
  568.         case OM_DISPOSE:            return (mDispose(cl, obj, (APTR)msg));
  569.         case MUIM_SystemWin_Update: return (mUpdate(cl, obj, (APTR)msg));
  570.         case MUIM_SystemWin_Print:  return (mPrint(cl, obj, (APTR)msg));
  571.     }
  572.  
  573.     return (DoSuperMethodA(cl, obj, msg));
  574. }
  575.  
  576. void PrintSystem( char *filename )
  577. {
  578.     BPTR handle;
  579.  
  580.     if (handle = HandlePrintStart(filename)) {
  581.         IterateList(PrintCallback, (void *)handle);
  582.     }
  583.  
  584.     HandlePrintStop();
  585. }
  586.  
  587. void SendSystemList( void )
  588. {
  589.     IterateList(SendCallback, NULL);
  590. }
  591.  
  592.